#include "main.h"

void Start_init()
{
    // 系统初始化
    System_Init();
    systickInit();

    // 初始化PID控制器
    PID_Init(&myPID,0.5,0.1,0.01,0,1);

    // 定时器0初始化
    Timer0_Init();

    // PWM初始化
    PWM_init();

    // IO初始化
    P0_Mode_OUT_PP(0xFF);
    P1_Mode_OUT_PP(0xFF);
    P2_Mode_OUT_PP(0xFF);
    P6_Mode_OUT_PP(0xFF);

    // 串口初始化
    Serial_Init(9600);
    Serial_SentStr("uart init ok\r\n");

    // LCD1602初始化
    LCD_Init();
    LCD_ShowString(1, 1, "power by zzy");
    Delay_ms(1000);
    LCD_WriteCommand(0x01); // 光标复位，清屏
    Delay_ms(100);

    // 初始化外部中断0
    IT0 = 1; // 使能INT0下降沿中断
    EX0 = 1;
    // 总中断使能
    EA = 1;
}

void main(void)
{
    Start_init();

    LCD_ShowString(1, 1, "speed");
    LCD_ShowString(1, 14, "PWM");
    LCD_ShowString(1, 7, "SP:");

    while (1)
    {
        // 从串口读取数据
        if(Serial_GetRecv_IDLE(rx_buffer) != 0){
            if (strchr(rx_buffer,'-'))
            {
                motor_duty_tag = atoi(rx_buffer)-65536;//负数处理
                LCD_ShowChar(2, 13, '-');
            }else{
                motor_duty_tag = atoi(rx_buffer); // 假设第一个字节是电机占空比值
                LCD_ShowChar(2, 13, '+');    
            }           
            memset(rx_buffer, 0, sizeof(rx_buffer));
        }

        LCD_ShowNum(2,6,&myPID.Setpoint,2);
        loop_contor(&myPID,motor_duty_tag);
        // PID控制
        motor_duty = PID_Calculate(&myPID,speed);
        PWM_Duty_Set(myPID.direction, motor_duty);

        if (motor_duty >= 0 && motor_duty <= 100 )
        {
            LCD_ShowNum(2, 14, motor_duty, 3);
        }
        else if (motor_duty <= 0 && motor_duty >= -100)
        {    
            LCD_ShowNum(2, 14, (motor_duty * -1), 3);
        }

        // if (inc == 0 && motor_duty > -100)
        // {
        //     motor_duty -= 5;
        //     Delay_ms(100);
        // }
        // else if (add == 0 && motor_duty < 100)
        // {
        //     motor_duty += 5;
        //     Delay_ms(100);
        // }
        LCD_ShowNum(2,1, speed, 3);

        Delay_ms(100); // 简单的延时
    }
}

// 电机中断计数(0端口P3^2,外部中断1端口P3^3)
void INT0_Isr() interrupt 0
{
    Motor_couter++;
}

void Timer0_Isr(void) interrupt 1
{
    // 定时器计数
    static uint16_t clock_tic = 0;
    static uint16_t Motor_couter_d = 0;

    clock_tic++;

    if (clock_tic >= 10000) // 1s
    {
        speed = Motor_couter - Motor_couter_d;
        Motor_couter_d = Motor_couter;

        // sprintf(uart_str, "%d", speed);
        // Serial_SentStr(uart_str);
        Serial_SentByte(speed);

        clock_tic = 0;
    }
}
#include "main.h"

/**
 * @brief 发送单个字符
 * @param dat 发送的数据
 */
void UartSend(char dat)
{
    while (busy)
        ;
    // 等待直到串口不忙
    busy = 1;   // 设置忙标志
    SBUF = dat; // 发送数据
    while (!TI)
        ;
    // 等待发送完成
    TI = 0;   // 清除发送中断标志
    busy = 0; // 清除忙标志
}

/**
 * @brief 发送字符串
 * @param  要发送的字符串
 */
void UartSendStr(char *p)
{
    while (*p)
    {
        UartSend(*p++);
    }
}

void Start_init()
{
    // 系统初始化
    System_Init();

    // 定时器0初始化
    Timer0_Init();

    // PWM初始化
    PWM_init();

    // IO初始化
    P0_Mode_OUT_PP(0xFF);
    P1_Mode_OUT_PP(0xFF);
    P2_Mode_OUT_PP(0xFF);

    // 串口初始化
    Uart1_Init();
    UartSendStr("uart init ok\r\n");

    // LCD1602初始化
    LCD_Init();
    LCD_ShowString(1, 1, "power by zzy");
    Delay_ms(1000);
    LCD_WriteCommand(0x01); // 光标复位，清屏
    Delay_ms(100);

    // 初始化外部中断0
    IT0 = 1; // 使能INT0下降沿中断
    EX0 = 1;
    // 总中断使能
    EA = 1;
}

void main(void)
{
    Start_init();

    LCD_ShowString(1, 1, "loop:");
    LCD_ShowString(1, 7, "speed");
    LCD_ShowString(1, 14, "PWM");

    while (1)
    {
        LCD_ShowNum(2, 1, Motor_couter, 5);
        LCD_ShowNum(2, 7, speed, 4);

        if (motor_duty >= 0 && motor_duty <= 100)
        {
            LCD_ShowChar(2, 13, '+');
            LCD_ShowNum(2, 14, motor_duty, 3);
            PWM_Duty_Set(1, motor_duty);
        }
        else if (motor_duty <= 0 && motor_duty >= -100)
        {
            LCD_ShowChar(2, 13, '-');
            LCD_ShowNum(2, 14, (motor_duty * -1), 3);
            PWM_Duty_Set(0, motor_duty * -1);
        }
        if (inc == 0 && motor_duty > -100)
        {
            motor_duty -= 10;
            Delay_ms(100);
        }
        else if (add == 0 && motor_duty < 100)
        {
            motor_duty += 10;
            Delay_ms(100);
        }

        Delay_ms(100); // 简单的延时
    }
}

// 电机中断计数(0端口P3^2,外部中断1端口P3^3)
void INT0_Isr() interrupt 0
{
    Motor_couter++;
}

//中断服务程序
void UartIsr() interrupt 4 using 1
{
    if (TI)											  //发送中断标志
    {
        TI = 0;   // 软件清零
        busy = 0; // 清除忙标志
    }
    if (RI) // 接收中断标志
    {
        RI = 0; // 软件清零
        motor_duty = SBUF; // 将接收到的数据放入缓冲区
        SetBits(P_SW2, 1 << 7);
        PWM0T1 = motor_duty; // 在计数值为100H地方输出低电平
        ClrBits(P_SW2, 1 << 7);
    }
}

void Timer0_Isr(void) interrupt 1
{
    // 定时器计数
    static uint16_t clock_tic = 0;
    static uint16_t Motor_couter_d = 0;

    clock_tic++;

    if (clock_tic >= 20000) // 2s
    {
        speed = Motor_couter - Motor_couter_d;
        Motor_couter_d = Motor_couter;

        sprintf(uart_str, "%d", speed);
        UartSendStr(uart_str);

        clock_tic = 0;
    }
}
